package com.uduew.sjd.utils
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.*
import android.os.Looper
import android.util.Log
import androidx.core.app.ActivityCompat
import java.io.IOException
import java.util.*

data class LocationDetail(
    val country: String?,
    val province: String?,
    val city: String?,
    val adminArea: String?,
    val subLocality: String?,
    val fullAddress: String?,
    val latitude: Double,
    val longitude: Double
)

/**
 * Android 原生定位服务封装类
 * 功能包含：
 * 1. 最后一次已知位置获取
 * 2. 实时位置更新
 * 3. 地址逆解析
 * 4. 完整权限管理
 */
class NativeLocationProvider(private val context: Context) {


    // 扩展函数将 Address 转换为 LocationDetail
    private fun Address.toLocationDetail(location: Location): LocationDetail {
        return LocationDetail(
            country = countryName,
            province = adminArea,
            city = locality,
            adminArea = subAdminArea,
            subLocality = subLocality,
            fullAddress = getAddressLine(0),
            latitude = location.latitude,
            longitude = location.longitude
        )
    }

    private val locationManager: LocationManager by lazy {
        context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    }

    private val geocoder: Geocoder by lazy {
        Geocoder(context, Locale.getDefault())
    }
    /**
     * 实时位置监听封装
     */
    fun registerLocationDetailListener(
        listener: (LocationDetail) -> Unit,
        provider: String = LocationManager.GPS_PROVIDER,
        minTimeMs: Long = 1000L,
        minDistanceM: Float = 10f
    ) {
        val locationListener = object : LocationListener {
            override fun onLocationChanged(location: Location) {
                reverseGeocode(location.latitude, location.longitude) { address ->
                    address?.let {
                        listener(it.toLocationDetail(location))
                    }
                }
            }
            // ... 其他回调方法 ...
        }
        registerLocationListener(locationListener, provider, minTimeMs, minDistanceM)
    }
    /**
     * 获取完整位置信息
     */
    fun getLocationDetail(callback: (LocationDetail?) -> Unit) {
        val location = getLastKnownLocation()
        if (location != null) {
            reverseGeocode(location.latitude, location.longitude) { address ->
                callback(address?.toLocationDetail(location))
            }
        } else {
            callback(null)
        }
    }

    // 位置监听器缓存
    private val listeners = mutableSetOf<LocationListener>()

    /**
     * 检查定位权限状态
     */
    fun checkLocationPermissions(): Boolean {
        return ActivityCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(
                    context,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 获取最后一次已知位置（带优先级策略）
     */
    @SuppressLint("MissingPermission")
    fun getLastKnownLocation(): Location? {
        if (!checkLocationPermissions()) {
            Log.w(TAG, "Location permissions not granted")
            return null
        }

        return try {
            // 优先获取GPS定位
            locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
                ?: locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
                ?: locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
        } catch (e: SecurityException) {
            Log.e(TAG, "Security exception: ${e.message}")
            null
        } catch (e: IllegalArgumentException) {
            Log.e(TAG, "Illegal provider: ${e.message}")
            null
        }
    }

    /**
     * 注册实时位置更新（支持多监听器）
     */
    @SuppressLint("MissingPermission")
    fun registerLocationListener(
        listener: LocationListener,
        provider: String = LocationManager.GPS_PROVIDER,
        minTimeMs: Long = 1000L,
        minDistanceM: Float = 10f
    ) {
        if (!checkLocationPermissions()) {
            Log.w(TAG, "Cannot register listener: permissions denied")
            return
        }

        try {
            if (locationManager.allProviders.contains(provider)) {
                locationManager.requestLocationUpdates(
                    provider,
                    minTimeMs,
                    minDistanceM,
                    listener,
                    Looper.getMainLooper()
                )
                listeners.add(listener)
            } else {
                Log.w(TAG, "Location provider $provider not available")
            }
        } catch (e: SecurityException) {
            Log.e(TAG, "Security exception: ${e.message}")
        }
    }

    /**
     * 注销位置监听器
     */
    fun unregisterLocationListener(listener: LocationListener) {
        try {
            locationManager.removeUpdates(listener)
            listeners.remove(listener)
        } catch (e: Exception) {
            Log.e(TAG, "Error removing listener: ${e.message}")
        }
    }

    /**
     * 地址逆解析（带重试机制）
     */
    fun reverseGeocode(
        latitude: Double,
        longitude: Double,
        maxResults: Int = 1,
        callback: (Address?) -> Unit
    ) {
        if (!Geocoder.isPresent()) {
            Log.w(TAG, "Geocoder service not available")
            callback(null)
            return
        }

        try {
            Thread {
                try {
                    val addresses = geocoder.getFromLocation(latitude, longitude, maxResults)
                    callback(addresses?.firstOrNull())
                } catch (e: IOException) {
                    Log.e(TAG, "Geocoder network error: ${e.message}")
                    callback(null)
                } catch (e: IllegalArgumentException) {
                    Log.e(TAG, "Invalid coordinates: $latitude,$longitude")
                    callback(null)
                }
            }.start()
        } catch (e: Exception) {
            Log.e(TAG, "Geocoder initialization failed: ${e.message}")
            callback(null)
        }
    }

    /**
     * 格式化地址信息
     */
    fun formatAddress(address: Address?): String {
        return address?.let {
            buildString {
                for (i in 0..it.maxAddressLineIndex) {
                    append(it.getAddressLine(i))
                    if (i < it.maxAddressLineIndex) append(", ")
                }
            }
        } ?: "Address not available"
    }

    companion object {
        private const val TAG = "LocationProvider"
    }
}

